package org.nanotek.lucene.index.search;

import java.util.List;

import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.nanotek.cms.domain.lucene.Index;
import org.nanotek.cms.domain.lucene.ScoreDocument;
import org.nanotek.lucene.query.BaseQueryDispatcher;
import org.nanotek.lucene.query.ContextKeys;
import org.nanotek.lucene.query.QueryContext;
import org.nanotek.lucene.query.QueryResult;

public class LocalResultsProvider implements Provider {

	private IndexSearcherProvider indexSearcherProvider;

	public LocalResultsProvider() {
	}

	/* (non-Javadoc)
	 * @see org.nanotek.lucene.index.search.Provider#search(java.lang.String)
	 */
	public QueryResult search(String searchPhrase) throws Exception
	{
		Index index = new Index();
		index.setIndexAlias("F:\\LuceneIndexBase\\BaseIndex");
		QueryContext queryContext = new QueryContext();
		queryContext.put(ContextKeys.CURRENT_INDEX, index);
		queryContext.setSearchPhrase(searchPhrase);
		queryContext.put(ContextKeys.TARGET_FIELD, "TextData");
		return fetchDocuments(queryContext);
	}


	/* (non-Javadoc)
	 * @see org.nanotek.lucene.index.search.Provider#search(org.nanotek.cms.domain.lucene.Index, java.lang.String)
	 */
	public QueryResult search(Index index , String searchPhrase) throws Exception
	{
		QueryContext queryContext = new QueryContext();
		queryContext.put(ContextKeys.CURRENT_INDEX, index);
		queryContext.setSearchPhrase(searchPhrase);
		//TODO set target fields outside the results provider class
		queryContext.put(ContextKeys.TARGET_FIELD, "TextData");
		return fetchDocuments(queryContext);
	}

	/* (non-Javadoc)
	 * @see org.nanotek.lucene.index.search.Provider#search(org.nanotek.lucene.query.QueryContext)
	 */
	@Override
	public QueryResult search(QueryContext queryContext) throws Exception
	{
		return fetchDocuments(queryContext);
	}

	private QueryResult fetchDocuments(QueryContext queryContext) throws Exception
	{
		BaseQueryDispatcher dispatcher = createQueryDispatcher(queryContext);
		return fetchDocuments(queryContext , dispatcher);
	}


	private static void printResult(List<ScoreDocument> documents) {
		{
			System.out.println(documents.size());
		}
	}

	private QueryResult fetchDocuments(QueryContext queryContext , BaseQueryDispatcher dispatcher) throws Exception {

		QueryResult queryResult = dispatcher.executeQuery(queryContext);
		if (queryResult.getDocuments() !=null && queryResult.getDocuments().size() > 0)
			printResult(queryResult.getDocuments());
		TopDocs topDocs = queryResult.getTopDocs();
		if (topDocs.scoreDocs.length > 0){
			ScoreDoc lastScoreDoc = topDocs.scoreDocs[topDocs.scoreDocs.length -1];
			QueryContext newContext = (QueryContext) queryContext.copy();
			newContext.put(ContextKeys.LAST_SCORED_DOC, lastScoreDoc);
			Integer pageSize = queryContext.getMaxHits();
			if (pageSize >= queryResult.getDocuments().size())
				return queryResult;
			QueryResult newResult = fetchDocuments(newContext ,dispatcher);
			if (newResult !=null && newResult.getDocuments() !=null)
			{
				queryResult.getDocuments().addAll(newResult.getDocuments());
			}
		}

		return queryResult;
	}

	private BaseQueryDispatcher createQueryDispatcher(QueryContext queryContext) throws Exception {
		BaseQueryDispatcher dispatcher = new BaseQueryDispatcher();
		if (indexSearcherProvider == null)
			indexSearcherProvider = new IndexSearcherProvider();
		IndexSearcher indexSearcher = indexSearcherProvider.getIndexSearcher((Index) queryContext.get(ContextKeys.CURRENT_INDEX));
		dispatcher.setIndexSearcher(indexSearcher);
		return dispatcher;
	}

	/* (non-Javadoc)
	 * @see org.nanotek.lucene.index.search.Provider#getIndexSearcherProvider()
	 */
	@Override
	public IndexSearcherProvider getIndexSearcherProvider() {
		return indexSearcherProvider;
	}

	/* (non-Javadoc)
	 * @see org.nanotek.lucene.index.search.Provider#setIndexSearcherProvider(org.nanotek.lucene.index.search.IndexSearcherProvider)
	 */
	@Override
	public void setIndexSearcherProvider(IndexSearcherProvider indexSearcherProvider) {
		this.indexSearcherProvider = indexSearcherProvider;
	}



}
